﻿using Framework.Components;
using Framework.Generics;
using Framework.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CmdService
{
    /// <summary>
    /// CMD程序
    /// </summary>
    public class CmdProgresss : Singleton<CmdProgresss>
    {
        public Log.Logger Logger { get; protected set; }

        protected Dictionary<string, string[]> argMap;  // 参数
        protected Process process;      //cmd进程
        
        public void Init(string[] args)
        {
            argMap = InitArgs(args);
            Log.Info("Cmd Args: " + StringUtils.ToString(argMap));

            // 内部日志处理
            Logger = new Log.Logger();
        }

        /// <summary>
        /// 启动运行
        /// </summary>
        public void Start()
        {
            try
            {
                // 线程启动
                var thread = new Thread(new ThreadStart(DoRun));
                thread.Start();
            }
            catch (Exception e)
            {
                Log.Error("服务启动错误: ", e);
            }
        }

        /// <summary>
        /// 执行运行
        /// </summary>
        private void DoRun()
        {
            // 获取启动参数
            var cmdStrs = Get("-r");
            Log.Info("执行cmd启动指令: " + StringUtils.ToString(cmdStrs));
            int csize = (cmdStrs != null) ? cmdStrs.Length : 0;
            if (csize <= 0)
            {
                Log.Error("没有指令");
                return;
            }
            var exeBin = cmdStrs[0];
            var args = (csize >= 2) ? cmdStrs[1] : "";

            try
            {
                // 启动程序
                Process process = CmdUtils.StartProcess(exeBin, args);
                // 绑定
                this.process = process;

                // 等待结束
                string retStr = CmdUtils.WaitProcess(process);
                Logger.Info("运行结果: \n" + retStr);
            }
            catch(Exception e)
            {
                Log.Error("启动执行错误! ", e);
            }
            // 清除绑定
            this.process = null;
        }
        /// <summary>
        /// 执行关闭
        /// </summary>
        private void DoStop()
        {
            // 执行停止
            var cmdStrs = Get("-s");
            Log.Info("执行cmd停止指令: " + StringUtils.ToString(cmdStrs));
            int csize = (cmdStrs != null) ? cmdStrs.Length : 0;
            if (csize <= 0)
            {
                // 没有参数, 强行kill
                Kill();
                return;
            }
            var exeBin = cmdStrs[0];
            var args = (csize >= 2) ? cmdStrs[1] : "";

            try
            {
                var retStr = CmdUtils.Execute(exeBin, args);
                Logger.Info("停止日志: \n" + retStr);
            }
            catch(Exception e)
            {
                Log.Error("关闭执行错误! ", e);
            }
        }

        /// <summary>
        /// 关闭处理
        /// </summary>
        /// <param name="timeout">等待关闭, 超时kill</param>
        public void Stop(int timeout = 30 * 1000)
        {
            // 线程启动
            var thread = new Thread(new ThreadStart(DoStop));
            thread.Start();

            // 等待进程停止
            long startTime = TimeUtils.GetCurrentTime();
            while (true)
            {
                // 检测测序是否接续
                if (process == null) { break; }

                // 检测超时
                long nowTime = TimeUtils.GetCurrentTime();
                long dt = nowTime - startTime;
                if (dt > timeout) { break; }
                Thread.Sleep(1000);
            }

            // 强制终止程序
            Kill();
        }
        
        /// <summary>
        /// 强制杀掉cmd进程
        /// </summary>
        public void Kill()
        {
            if (process != null)
            {
                process.Kill();
                process = null;
            }
        }

        /// <summary>
        /// 获取参数
        /// </summary>
        public string[] Get(string key)
        {
            return (argMap.ContainsKey(key)) ? argMap[key] : null;
        }

        /// <summary>
        /// 获取单个参数
        /// </summary>
        public string GetOne(string key)
        {
            var values = Get(key);
            return (values != null && values.Length > 0) ? values[0] : null;
        }

        /// <summary>
        /// 是否存在值
        /// </summary>
        public bool ContainsKey(string key)
        {
            return argMap.ContainsKey(key);
        }

        /// <summary>
        /// 解析参数
        /// </summary>
        private static Dictionary<string, string[]> InitArgs(string[] args)
        {
            var argMap = new Dictionary<string, string[]>();
            var argList = new List<string>();
            string pravKey = "-other";

            // 遍历参数
            foreach (string arg in args)
            {
                if (string.IsNullOrEmpty(arg)) { continue; }
                // 检测参数, 是否是-开头的参数指令
                if (arg.IndexOf("-") == 0)
                {
                    // 设置参数
                    argMap[pravKey] = argList.ToArray();
                    argList.Clear();
                    pravKey = arg;
                    continue;
                }

                // 添加参数
                argList.Add(arg);
            }

            // 最后的参数
            argMap[pravKey] = argList.ToArray();
            argList.Clear();

            return argMap;
        }

    }
}
